CS 211 Lesson 10
Program Design
Quote:
"Hearing is one of the body's five senses. But listening is an art." Frank Tyger
Lesson Objectives:
Understand the steps in the program design process
Know what an algorithm is
Know what pseudocode is and how to use it
Understand top-down design and step-wise refinement
Lesson:
I. MATLAB Concepts
(none for this lesson)
II. Good Programming Practices
A. The Program Design Process
- There are 4 general steps to the "classic" program design process:
Understand the problem
Design a solution (Design inputs, design outputs, and design data processing algorithms)
Translate the solution into a program (programming, or sometimes called coding)
Test and debug the program
Understanding the problem is often the most challenging step.
Typically the customer who needs the software does not fully understand their own requirements.
For smaller problems, understanding the problem may not be very difficult, if you understand the problem domain. However, for large problems, understanding the problem can take much effort and much time.
Attempting to solve a problem you do not fully understand can lead to solving the wrong problem.
- it.
Translating a solution into a program (i.e., programming) typically is the easiest step for an experienced programmer.
However, novice programmers sometimes spend a lot of time encoding a solution to a problem and debugging
One software expert (Fred Brooks) estimates that on large projects, the amount of time required for these tasks are:
1/3 of the time on planning (understanding the problem and designing a solution)
1/6 of the time on programming
1/2 of the time on testing and debugging
As a general rule, the more time you spend on steps 1 and 2 (understanding the problem and design), the less time you should need to spend on programming and debugging.
Following these four steps, in order, is an ideal which is not always achievable.
Designing a software solution for small, well-defined problems is much easier than designing a software solution for the typical Department of Defense (DoD) problem. Developing skills in designing solutions for small software problems (software engineering "in the small") should help you deal with larger engineering design challenges later.
B. Designing a solution
An algorithm is a step-by-step plan for solving a problem.
An algorithm may be expressed in programming language code, or in a more informal English-like notation.
Pseudocode is an informal combination of English and code which expresses an algorithm.
The following is an example of an algorithm written in pseudocode:
set Secret_number to a random integer from 1 to 100
set User_guess to 0
repeat until User_guess = Secret_number
get a valid value for User_guess from the user
if User_guess > Secret_number
tell the user their guess is too high
otherwise, if User_guess < Secret_number
tell the user their guess is too low
otherwise
tell the user their guess is correct
thank the user for playing
Note that indenting pseudocode helps show the blocks of code which are executed, skipped, or repeated as units.
A pseudocode algorithm may leave out many of the details required by an actual MATLAB program.
Using pseudocode can help you focus on the solution design rather than syntactic and MATLAB-specific details.
You can test a well-written pseudocode algorithm with pencil and paper. This is sometimes called desk checking or performing a walk-thru.
It is common to include the major steps of your algorithm as comments in your program code.
One well-established strategy for designing software solutions is top-down design with step-wise refinement.
Top-down design involves developing a high-level plan for solving the whole problem, and then breaking that plan down into smaller subtasks which may be solved independently.
Step-wise refinement involves adding details to your solution, one subtask at a time.
Top-down design and step-wise refinement are particularly useful once you begin to develop larger programs which can be divided into independent parts, each implemented with one or more separate functions.
III. Algorithms
A. Find the roots of an equation using the bisection method.
The bisection method for finding roots of an equation f(x) is fairly simple. A root of an equation typically occurs when the equation crosses the x axis. Therefore, a root occurs between two locations along the plot of the equation when one location is above the x axis and the other location is below the x axis. Using these "upper" and "lower" points, the bisection method calculates the mid-point of their interval and redefines the interval containing the root based on this mid-point. When done repeatedly, the interval that brackets the root will get smaller and smaller and "close in on" the root value. (Note that this method cannot find root values of all equations. For example, it is impossible to create the bisection interval in cases where the equation just "touches" the x-axis but never crosses the axis, . In addition, some equations have no real roots -- only imaginary roots.)
A graphical example of the bisection method is shown below.
The bisection method, written in pseudocode (which is similar to code but ignores language syntax issues) might be written as:
Prompt the user to enter two "guesses" for the root, x1 and x2
while the function at the two "guesses" do not have different signs
Prompt the user to enter two "guesses" for the root, x1 and x2
Calculate the mid-point between the two "guesses"
while the absolute value of f(mid_point) is greater than some small tolerance
if sign of f(mid_point) is different than f(x1), set x2 equal to the mid_point
else set x1 equal to the mid_point
Calculate the mid-point between the two guesses, x1 and x2
Report the mid_point as a root of the function f(x)This pseudocode can be written in MATLAB in a variety of ways. One possible translation is shown below:
Tolerance = 1.0e-10; clc(); fprintf('This function will find a root of an equation (where\n'); fprintf('the equation evaluates to zero) using the bisection\n'); fprintf('numerical technique.\n'); X1 = input('Please enter a first guess where a root might be : '); X2 = input('Please enter a second guess where a root might be : '); while sign(f(X1)) == sign(f(X2)) fprintf('f(%g) = %g has the same sign as f(%g) = %g.\n', X1, f(X1), X2, f(X2)); fprintf('We need points that bracket a root above and below the x-axis.\n'); fprintf('Please re-enter two different guesses.\n'); X1 = input('Please enter a first guess where a root might be : '); X2 = input('Please enter a second guess where a root might be : '); end fprintf('f(%g) = %g has a different sign compared to f(%g) = %g.\n', X1, f(X1), X2, f(X2)); fprintf('We can proceed with the bisection method.\n'); X_middle = (X1 + X2) * 0.5; while abs(f(X_middle)) > Tolerance if sign(f(X1)) ~= sign(f(X_middle)) X2 = X_middle; elseif sign(f(X2)) ~= sign(f(X_middle)) X1 = X_middle; else % f(X_middle) is exactly zero and the root has been found break end X_middle = (X1 + X2) * 0.5; fprintf('Interval is now %0.10f (%0.10f) to %0.10f (%0.10f)\n', X1, f(X1), X2, f(X2)); end fprintf('Root: f(%0.15f) = %0.15f\n', X_middle, f(X_middle));Notice that the pseudocode algorithm is totally concentrated on the problem solving task.
In contrast, the MATLAB program must deal with the details of the programming language, such as testing for the sign of a value.
Performing problem solving and programming as distinct tasks is extremely beneficial to the overall software development process.
Lab Work: Lab 10
References: Chapman Textbook: sections 3.1-3.2